package com.t2t.top.framework.zk;

import com.t2t.top.framework.util.SystemInfoUtils;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.RetryNTimes;
import org.apache.zookeeper.CreateMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.*;

public class ZookeeperRegister {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    public static final String ZK_PATH_ROOT = "/devops/monitor";
    public static final int connectionTimeout = 5000;
    public static final String SPLIT = "/";//分隔符


    private String zkAddress;
    private String defualtNodeName;
    private CuratorFramework client;

    public ZookeeperRegister(String zkAddress, String serverName) {
        try {
            this.zkAddress = zkAddress;
            this.defualtNodeName = serverName;

            client = CuratorFrameworkFactory.newClient(zkAddress, new RetryNTimes(3, connectionTimeout));
            client.start();
            logger.info("zk client start successfully!");
        } catch (Exception e) {
            logger.info("zookeeper启动失败", e);
        }
    }

    public void register() {
        try {
            register(SystemInfoUtils.getLocalAddress(), SystemInfoUtils.getServerPort());
        } catch (Exception e) {
            logger.error("注册失败", e);
        }
    }

    /**
     * 注册zookeeper
     */
    public void register(String appServerIP, String appServerPort) throws Exception {
        logger.info("zkAddress={},defualtNodeName={},appServerIP={},appServerPort={}", zkAddress, defualtNodeName, appServerIP, appServerPort);

        String groupNodeName = getCurrentGroupFullName();
        String nodeName = groupNodeName + SPLIT + appServerIP + ":" + appServerPort;
        logger.info("nodeName={}", nodeName);
        if (client.checkExists().forPath(groupNodeName) == null) {
            client.create().creatingParentsIfNeeded().forPath(groupNodeName);
        }
        if (client.checkExists().forPath(nodeName) != null) {
            client.delete().forPath(nodeName);
        }

        String data = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        logger.info("Zookeeper产生data{}", data);
        if (client.checkExists().forPath(nodeName) == null) {
            client.create().withMode(CreateMode.EPHEMERAL).forPath(nodeName, data.getBytes());
        }
        client.setData().forPath(nodeName, data.getBytes());
    }

    /**
     * 获取根节点下所有的子节点
     */
    public Map<String, List<ZookeeperNode>> rootTreeNodes() {
        Map map = new HashMap();
        try {
            List<String> nodes = client.getChildren().forPath(ZK_PATH_ROOT);
            for (String nodeName : nodes) {
                map.put(nodeName, getZookeeperNodes(nodeName));
            }
        } catch (Exception e) {
            logger.error("读取失败", e);
        }
        return map;
    }

    /**
     * 获取当期组的节点
     */
    public List<ZookeeperNode> getCurrentZookeeperNodes() {
        return getZookeeperNodes(this.defualtNodeName);
    }

    /**
     * 获取指定组的节点
     */
    public List<ZookeeperNode> getZookeeperNodes(String groupNodeName) {
        try {
            if (client.checkExists().forPath(ZK_PATH_ROOT + SPLIT + groupNodeName) != null) {
                List<String> subNodes = client.getChildren().forPath(ZK_PATH_ROOT + SPLIT + groupNodeName);
                List<ZookeeperNode> zookeeperNodes = new ArrayList();
                for (String subNode : subNodes) {
                    ZookeeperNode zn = getZNodeByGroupNameAndNodeName(groupNodeName, subNode);
                    zookeeperNodes.add(zn);
                }
                return zookeeperNodes;
            }
        } catch (Exception e) {
            logger.error("读取失败", e);
        }
        return new ArrayList();
    }

    /**
     * 根据节点名称获取内容
     */
    public ZookeeperNode getZNodeByGroupNameAndNodeName(String groupNodeName, String noteName) {
        ZookeeperNode zn = null;
        try {
            String fullNoteName = ZK_PATH_ROOT + SPLIT + groupNodeName + SPLIT + noteName;
            logger.info("fullNoteName={}", fullNoteName);
            if (client.checkExists().forPath(fullNoteName) != null) {
                String data = new String(client.getData().forPath(fullNoteName));
                zn = new ZookeeperNode(noteName, data);
                return zn;
            }
        } catch (Exception e) {
            logger.error("读取失败", e);
        }
        return zn;
    }

    /**
     * 根据节点名称获取当前节点内容
     */
    public ZookeeperNode getZNodeByCurrentNodeName(String noteName) {
        return getZNodeByGroupNameAndNodeName(defualtNodeName, noteName);
    }

    /**
     * 获取当前组全名
     */
    public String getCurrentGroupFullName() {
        return ZK_PATH_ROOT + SPLIT + defualtNodeName;
    }
}